#!/bin/sh
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Log all calls, with arguments, to /var/log/messages
logger "$0" "$@"

XINPUT=/usr/bin/xinput

export DISPLAY=:0
export XAUTHORITY=/home/chronos/.Xauthority

. /opt/google/mouse/common

PROG=`basename $0`
COMMAND=$1

# On disk preferences
PREF_SENS_FILE=/home/chronos/user/touchpad_sensitivity
PREF_SENS_VALID="[12345]"
PREF_SENS_DEFAULT=3
PREF_TAP_FILE=/home/chronos/user/touchpad_tap_enable
PREF_TAP_VALID="[01]"
PREF_TAP_DEFAULT=0
PREF_T5R2_3FCLICK_FILE=/home/chronos/user/touchpad_t5r2_3f_click_enable
PREF_T5R2_3FCLICK_VALID="[01]"
PREF_T5R2_3FCLICK_DEFAULT=0
PREF_3FSWIPE_FILE=/home/chronos/user/touchpad_3f_swipe_enable
PREF_3FSWIPE_VALID="[01]"
PREF_3FSWIPE_DEFAULT=0
PREF_TAPDRAG_FILE=/home/chronos/user/touchpad_tap_drag_enable
PREF_TAPDRAG_VALID="[01]"
PREF_TAPDRAG_DEFAULT=0

# For tpcontrol firmware trials
TP_FIRMWARE_TRIAL_SELECTION_FILE=/var/cache/touch_trial/selection
TP_FIRMWARE_TRIAL_CHOICES_FILE=/opt/google/touchpad/firmware/choices

print_firmware_selection() {
  selected=$(cat "${TP_FIRMWARE_TRIAL_SELECTION_FILE}")
  while read CHOICE; do
    if [ "${selected}" = "${CHOICE}" ]; then
      printf "[${CHOICE}] "
    else
      printf "${CHOICE} "
    fi
  done < "${TP_FIRMWARE_TRIAL_CHOICES_FILE}"
  printf "\n"
}

usage() {
  echo "Usage:"\
    "$PROG {status|log ['alt']|tap_dragging [on|off]|"\
    "taptoclick [on|off]|sensitivity [1-5]|"\
    "t5r2_three_finger_click [on|off]|"\
    "three_finger_swipe [on|off]|"\
    "set <property> <value>|add|listdev}"
}

# echos "0" (off) or "1" (on) on success, or nothing on failure.
parse_bool() {
  local value="$1"
  case $value in
  "on"|"1")
    echo "1"
    ;;
  "off"|"0")
    echo "0"
    ;;
  esac
}

# Sets VALID to 1 (valid input) or 0 (invalid input)
apply_on_off_prop() {
  local prop_name="$1"
  local value="$2"
  local pref_name="$3"

  local num_val=$(parse_bool "$value")
  if [ -n "$num_val" ]; then
    for DEVICE in $DEVICES ; do
      $XINPUT set-prop $DEVICE "$prop_name" "$num_val"
    done
    store_pref "$pref_name" "$num_val"
    VALID=1
  else
    VALID=0
  fi
}

# If no args passed, print usage
if [ $# = 0 ] ; then
  usage
  exit 1
fi

DEVICES="$(find_pad)"
while true; do
  COMMAND=$1
  VALID=0

  if [ $# = 0 ] ; then
    # If no commands remain, we're done
    exit 0
  elif [ "$COMMAND" = "status" ] ; then
    for DEVICE in $DEVICES ; do
      echo DEVICE: $DEVICE
      $XINPUT list-props $DEVICE
    done
    VALID=1
    shift
  elif [ "$COMMAND" = "log" -a \( $# = 1 -o $# = 2 \) ] ; then
    # This must be the last command on the line b/c it has variable args
    now=$(date '+%Y%m%d-%H%M%S')
    for DEVICE in $DEVICES ; do
      DEVNAME="$(get_device_name $DEVICE | sed 's/[^a-zA-Z0-9]/_/g')"
      raw_file=/var/log/xorg/touchpad_activity_log.txt
      cmt_log_file=/var/log/xorg/cmt_input_events.dat
      $XINPUT set-prop $DEVICE "Logging Notify" 1
      $XINPUT set-prop $DEVICE "Dump Debug Log" 1

      # Wait for writing to the files to complete. We do this by waiting for
      # two consecutive checks in which the file size of the logs doesn't
      # change.
      raw_size="-1"
      cmt_size="-1"
      max_iterations=6
      while true; do
        raw_size_new=$(stat -c %s $raw_file)
        cmt_size_new=$(stat -c %s $cmt_log_file)
        if [ $raw_size -eq $raw_size_new -a $cmt_size -eq $cmt_size_new ]; then
          break
        fi
        max_iterations=$((max_iterations - 1))
        if [ $max_iterations -lt 0 ]; then
          break
        fi
        sleep 0.5
        raw_size=$raw_size_new
        cmt_size=$cmt_size_new
      done

      out_dir=/home/chronos/user/log
      if [ "$2" = "alt" ]; then
        out_dir=/debugd/touchpad
      fi
      out_prefix=touchpad_activity_
      out_file="${out_dir}/${out_prefix}${now}.$DEVICE.$DEVNAME"
      cmt_out_prefix=cmt_input_events_
      cmt_out_file="${out_dir}/${cmt_out_prefix}${now}.$DEVICE"
      if [ ! -d $out_dir ]; then
        echo "User not logged in, so not moving log to user dir"
      else
        gzip -c --stdout "$raw_file" > "$out_file"
        gzip -c --stdout "$cmt_log_file" > "$cmt_out_file"
        # Delete old log files
        del="$(ls -t ${out_dir}/${out_prefix}* | grep -v ${now})"
        del="${del} $(ls -t ${out_dir}/${cmt_out_prefix}* | grep -v ${now})"
        for file in $del ; do
          rm -f "$file"
        done
      fi
    done
    VALID=1
    shift $#
  elif [ "$COMMAND" = "tap_dragging" -a -n "$2" ] ; then
    VALUE=$2
    apply_on_off_prop "Tap Drag Enable" "$VALUE" "TAPDRAG"
    shift 2
  elif [ "$COMMAND" = "taptoclick" -a -n "$2" ] ; then
    VALUE=$2
    apply_on_off_prop "Tap Enable" "$VALUE" "TAP"
    shift 2
  elif [ "$COMMAND" = "sensitivity" -a -n "$2" ] ; then
    VALUE=$2
    for DEVICE in $DEVICES ; do
      if ! is_multitouch_mouse ${DEVICE}; then
        $XINPUT set-prop $DEVICE "Pointer Sensitivity" "$VALUE"
      fi
      $XINPUT set-prop $DEVICE "Scroll Sensitivity" "$VALUE"
    done
    store_pref SENS "$VALUE"
    VALID=1
    shift 2
  elif [ "$COMMAND" = "three_finger_click" -a -n "$2" ] ; then
    # 3F click is no longer experimental -> ignore this command
    true
    shift 2
  elif [ "$COMMAND" = "t5r2_three_finger_click" -a -n "$2" ] ; then
    VALUE=$2
    apply_on_off_prop "T5R2 Three Finger Click Enable" "$VALUE" "T5R2_3FCLICK"
    shift 2
  elif [ "$COMMAND" = "three_finger_swipe" -a -n "$2" ] ; then
    VALUE=$2
    apply_on_off_prop "Three Finger Swipe Enable" "$VALUE" "3FSWIPE"
    shift 2
  elif [ "$COMMAND" = "set" -a -n "$2" -a -n "$3" ] ; then
    PROP=$2
    VALUE=$3
    for DEVICE in $DEVICES ; do
      $XINPUT set-prop $DEVICE "$PROP" "$VALUE"
    done
    VALID=1
    shift 3
  elif [ "$COMMAND" = "firmware" -a $# = 1 ]; then
    # firmware must be the last command on the line
    if [ -e "${TP_FIRMWARE_TRIAL_SELECTION_FILE}" ] &&
       [ -e "${TP_FIRMWARE_TRIAL_CHOICES_FILE}" ]; then
      # List firmwares available for trial
      print_firmware_selection
    else
      echo "Touchpad trial firmwares not supported."
    fi
    VALID=1
    shift
  elif [ "$COMMAND" = "firmware" -a $# = 2 ]; then
    # firmware must be the last command on the line
    VALUE=$2
    if [ -e "${TP_FIRMWARE_TRIAL_SELECTION_FILE}" ] &&
       [ -e "${TP_FIRMWARE_TRIAL_CHOICES_FILE}" ]; then
      FOUND=0
      while read CHOICE; do
        if [ "${VALUE}" = "${CHOICE}" ]; then
          FOUND=1
          break
        fi
      done < "${TP_FIRMWARE_TRIAL_CHOICES_FILE}"
      if [ ${FOUND} -eq 1 ]; then
        printf "${VALUE}" > "${TP_FIRMWARE_TRIAL_SELECTION_FILE}"
        echo "Selected ${VALUE} as touchpad trial firmware. Reboot to apply."
      else
        echo "Please select one of these :"
        print_firmware_selection
      fi
    else
      echo "Touchpad trial firmwares not supported."
    fi
    VALID=1
    shift 2
  elif [ "$COMMAND" = "add" ] ; then
    # New device. Set sensitivity/tap enable
    # Give some time for device to arrive, if necessary
    DEVICE=$(wait_and_get_added_xinput_id)
    if [ -z "$DEVICE" ]; then
      logger New touchpad device not found with xinput: $DEVNAME
    fi
    if ! is_multitouch_mouse ${DEVICE}; then
      $XINPUT set-prop $DEVICE "Pointer Sensitivity" "$(load_pref SENS)"
    fi
    $XINPUT set-prop $DEVICE "Scroll Sensitivity" "$(load_pref SENS)"
    $XINPUT set-prop $DEVICE "Tap Drag Enable" "$(load_pref TAPDRAG)"
    $XINPUT set-prop $DEVICE "Tap Enable" "$(load_pref TAP)"
    $XINPUT set-prop $DEVICE "T5R2 Three Finger Click Enable" \
        "$(load_pref T5R2_3FCLICK)"
    $XINPUT set-prop $DEVICE "Three Finger Swipe Enable" \
        "$(load_pref 3FSWIPE)"
    VALID=1
    shift
  elif [ "$COMMAND" = "listdev" ] ; then
    find_pad
    VALID=1
    shift
  fi

  if [ $VALID = 0 ] ; then
    usage
    exit 1
  fi
done
